#include <glib.h>

typedef struct mydata_tag {
    int id;
    char *name;
}my_data_t;

void my_free_func(gpointer data)
{
    my_data_t *mydata = NULL;
    mydata = (my_data_t *)data;

    if(NULL != mydata->name) {
    	//g_printf("free mydata->name: %s \n", mydata->name);
    	g_free(mydata->name);
    }

    return;
}

void my_printf(gpointer data, gpointer user_data)
{
    g_printf("my_printf: id=%d, name=%s, user_data=%s\n", ((my_data_t *)data)->id, ((my_data_t *)data)->name, (char *)user_data);
}

gpointer my_deep_copy_func(gconstpointer src, gpointer data)
{
    char new_name[16] = {0};
    my_data_t *src_data = (my_data_t *)src;
    my_data_t *mydata = (my_data_t *)g_malloc(sizeof(my_data_t));
    mydata->id = src_data->id;
    g_snprintf(new_name, 16, "[new]%s", src_data->name);
    mydata->name = g_strdup(new_name);
    return mydata;
}

static void test_slist_deep_copy(void)
{
    GSList *slist = NULL;
    GSList *clist = NULL;
    GSList *s;
    my_data_t mydata[16];

    char name[16] = {0};

    int i;
    memset(mydata, 0, sizeof(my_data_t)*5);
    for(i=0;i<5;i++) {
        mydata[i].id = i;
        g_snprintf(name, 16, "data is %d", i);
        mydata[i].name = g_strdup(name);
        slist = g_slist_append(slist, (gpointer)&mydata[i]);
    }

    g_slist_foreach(slist, my_printf, "slist");

    clist = g_slist_copy_deep(slist, my_deep_copy_func, NULL);

    g_slist_foreach(clist, my_printf, "clist");

    g_slist_free_full(slist, my_free_func);
    g_slist_free_full(clist, my_free_func);
    //g_slist_free(clist);
}

gint main (gint argc, gchar *argv[])
{
    g_test_init (&argc, &argv, NULL);

    g_test_add_func ("/slist/deep_copy", test_slist_deep_copy);

    return g_test_run ();
}
